package com.css.sword.knowing.search.util;

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;

import com.css.sword.knowing.search.SearchResult;
import com.css.sword.knowing.search.SuggestDocument;
import com.css.sword.knowing.search.SuggestInput;
import com.css.sword.knowing.search.aggregation.AggResult;
import com.css.sword.knowing.search.aggregation.BucketResult;
import com.css.sword.knowing.search.aggregation.MetricsResult;
import com.css.sword.knowing.search.aggregation.SearchAndAggResult;
import com.css.sword.knowing.search.comm.SearchConst;

public class ToJson {

    public static String mapToJson(Map<String, Object> map, String systemID) throws IOException {
        XContentBuilder jsonBuild = getJsonBuilder(map, systemID);
        return jsonBuild.string();
    }

	public static long mapSize(Map<String, Object> map, String systemID) throws IOException {
		long size = 0;
		// 使用XContentBuilder创建json数据
		XContentBuilder jsonBuild = getJsonBuilder(map, systemID);
		size = jsonBuild.bytes().length();
		// jsonData = jsonBuild.string();
		// System.out.println(jsonData);

		return size;
	}

	public static XContentBuilder getJsonBuilder(Map<String, Object> map, String systemID) throws IOException {
		XContentBuilder jsonBuild = XContentFactory.jsonBuilder();
		// jsonBuild.startObject();

		if(null != systemID && !systemID.isEmpty())
			map.put(SearchConst.SYSTEMID_FIELD, systemID);
        jsonBuild.map(map);

        /*
         * Iterator it = map.keySet().iterator(); while(it.hasNext()) { String
         * key = (String)it.next(); jsonBuild.field(key,map.get(key)); }
         */
        // jsonBuild.field(SearchConst.SYSTEMID_FIELD,systemID);
        // jsonBuild.endObject();
        return jsonBuild;
    }

    public static XContentBuilder getSuggestJson(SuggestInput suggestInput) throws IOException {
        XContentBuilder mapping = XContentFactory.jsonBuilder().startObject();
        mapping = mapping.startObject(suggestInput.getSuggestFieldName());
        for (SuggestDocument sd : suggestInput.getSuggestDocuments()) {
            mapping.array("input", sd.getInput()).field("output", sd.getOutput());
            if (suggestInput.isWeight()) {
                mapping.field("weight", sd.getWeight());
            }
            if (suggestInput.isPayload()) {
                mapping.field("payload", sd.getPayload());
            }
        }

        mapping.endObject();
        mapping.endObject();
        return mapping;
    }

	public static void getSearchResultJson(XContentBuilder jsonBuilder,SearchResult rs) {

		try {
			jsonBuilder.startObject("searchResult");

				jsonBuilder.field("count", rs.getNum());
				jsonBuilder.field("total", rs.getTotalNum());
				jsonBuilder.field("pageNum", rs.getPageNum());
				jsonBuilder.field("pageSize", rs.getPageSize());

				jsonBuilder.startArray("docs");
				List<Map> data = rs.getData();
				String key = null;
				Object value = null;
				for (Map<String, String> fields : data) {
					jsonBuilder.startObject();
					Iterator<String> it = fields.keySet().iterator();
					while (it.hasNext()) {
						key = it.next();
						value = fields.get(key);
						jsonBuilder.field(key, value);
					}
					jsonBuilder.endObject();
				}
				jsonBuilder.endArray();

			jsonBuilder.endObject();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private static void getMetricsResult(List<MetricsResult> l) {

		for (MetricsResult mr : l) {
			System.out.println(mr.getAggName());
			List<Map<String, Number>> metricsList = mr.getMetrics();
			for (Map<String, Number> map : metricsList) {
				if (map != null) {
					for (String metricsKey : map.keySet()) {
						System.out.print(metricsKey + ":");
						System.out.println(map.get(metricsKey));
					}
				}
			}
		}
	}

	public static void getAggResult(AggResult ar, String spaceStr) {

		List<MetricsResult> l = ar.getMetricsResults();
		if (null != l) {
			getMetricsResult(l);
		}

		Map<String, List<BucketResult>> bMap = ar.getBucketResultMap();
		if (null != bMap) {
			for (String aggName : bMap.keySet()) {
				List<BucketResult> bucketResults = bMap.get(aggName);
				System.out.println(spaceStr + aggName);
				for (BucketResult br : bucketResults) {
					Map<String, AggResult> aggResultMap = br.getBucketAgg();
					// System.out.println("docNumber:" + br.getDocNumber());
					if (null != aggResultMap) {
						for (String bucketKey : aggResultMap.keySet()) {
							System.out.println("  " + spaceStr + bucketKey + " - [" + br.getDocNumber() + "]");
							getAggResult(aggResultMap.get(bucketKey), "    " + spaceStr);

						}
					}
				}
			}
		}
	}

	private static void aggResultJSON(XContentBuilder jsonBuilder, AggResult ar) throws IOException {
		Map<String, List<BucketResult>> bMap = ar.getBucketResultMap();
		if (null != bMap) {
			for (String aggName : bMap.keySet()) {
				List<BucketResult> bucketResults = bMap.get(aggName);
				jsonBuilder.startArray(aggName);

				for (BucketResult br : bucketResults) {
					Map<String, AggResult> aggResultMap = br.getBucketAgg();

					if (null == aggResultMap)
						continue;

					for (String bucketKey : aggResultMap.keySet()) {

						jsonBuilder.startObject();

						jsonBuilder.field("name", bucketKey);
						jsonBuilder.field("count", br.getDocNumber());

						aggResultJSON(jsonBuilder, aggResultMap.get(bucketKey));

						jsonBuilder.endObject();
					}
				}
				jsonBuilder.endArray();
			}
		}
	}

	public static void getAggResultJson(XContentBuilder jsonBuilder, AggResult aggResult) throws IOException {
	
		jsonBuilder.startObject("facet");
		aggResultJSON(jsonBuilder, aggResult);

		jsonBuilder.endObject();
	}

	public static void main(String[] args) throws IOException {
		Map<String, Object> m = new HashMap<String, Object>();
		m.put("1", "1中国");
		m.put("2", "2");
		System.out.println(mapSize(m, "12345"));
		// mapToJson(m,"4444");
	}
}
